package com.cyys.modules.generator.service;

import com.cyys.common.ql.AR;
import com.cyys.common.services.CyysBaseService;
import com.cyys.common.utils.StringUtil;
import com.cyys.common.utils.list.ListUtil;
import com.cyys.modules.core.sysParam.GeneratorUtil;
import com.cyys.modules.core.utils.FileUtil;
import com.cyys.modules.core.utils.FreemarketConfigUtil;
import com.cyys.modules.generator.dao.GeneratorFieldDao;
import com.cyys.modules.generator.dao.GeneratorTableDao;
import com.cyys.modules.generator.model.GeneratorConfigure;
import com.cyys.modules.generator.model.GeneratorField;
import com.cyys.modules.generator.model.GeneratorTable;
import com.cyys.modules.system.model.user.Menu;
import com.cyys.modules.system.service.user.MenuService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service("generatorTableService")
@Transactional(readOnly = true)
public class GeneratorTableService extends CyysBaseService<GeneratorTableDao, GeneratorTable> {

    @Resource
    GeneratorFieldDao generatorFiledDao;

    @Resource
    MenuService menuService;

    /**
     * 创建新表
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = false)
    public AR createAllTable(){
        List<GeneratorTable> list = dao.listTable();
        /**配置表基础设置**/
        GeneratorConfigure configure = GeneratorUtil.get();
        /**系统表不做初始化**/
        List<String> systemNameList = new ArrayList<>(Arrays.asList(configure.getSystemTable().split(",")));
        /**现有所有表加入List中不新增**/
        List<GeneratorTable> currentTableList = dao.selectList(null);
        for(GeneratorTable currentTable :currentTableList){
            systemNameList.add(currentTable.getTableName());
        }

        /**创建所有表和列***/
        for(GeneratorTable generatorTable : list){
            /***比较现有表和数据库中的表，如果存在不进行操作***/
            if(!systemNameList.contains(generatorTable.getTableName())){
                createTable(configure, generatorTable);
            }
        }
        return AR.ok("表生成成功");
    }

    /**
     * 重新生成表
     * @param id
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = false)
    public AR reloadTable(String id){
        /**配置表基础设置**/
        GeneratorConfigure configure = GeneratorUtil.get();
        /**查询原表***/
        GeneratorTable generatorTable = getById(id);
        /*****删除原表****/
        deleteById(id);
        /********查询数据库并生成原表********/
        generatorTable = dao.getTableByName(generatorTable.getTableName());
        createTable(configure, generatorTable);
        return AR.ok("重新创建表成功");
    }

    private Map<String,Object> getFileTypeByDataType(String columnType,String tinyintTransType){
        Map<String,Object> map = new HashMap<>();
        String fileType = new String();
        int length1 = -1;
        int length2 = -1;
        int startKh=columnType.indexOf("(");
        if(startKh>=0) {
            int endKh = columnType.indexOf(")", startKh);
            String[] fanwei=columnType.substring(startKh+1,endKh).split(",");
            if((fanwei.length>1&&"0".equals(fanwei[1]))||fanwei.length==1){
                length1=Integer.parseInt(fanwei[0]);
                if(fanwei.length>1) {
                    length2 = Integer.valueOf(fanwei[1]);
                }
            }
        }
        if (columnType.contains("tinyint")) {
            fileType = tinyintTransType;
        }
        else if (columnType.contains("int") || columnType.contains("smallint")) {
            if(length1 > 0 && length1 <= 9)
                fileType = Integer.class.getSimpleName();
            else
                fileType = Long.class.getSimpleName();
        } else if (columnType.contains("bigint")) {
            fileType = Long.class.getSimpleName();
        } else if (columnType.contains("float")) {
            fileType = Float.class.getSimpleName();
        } else if (columnType.contains("double")) {
            fileType = Double.class.getSimpleName();
        } else if (columnType.contains("time") || columnType.contains("date") || columnType.contains("datetime") || columnType.contains("timestamp")) {
            fileType = Date.class.getSimpleName();
        } else if (columnType.contains("varchar") || columnType.contains("text")|| columnType.contains("char")
                || columnType.contains("clob")||columnType.contains("blob")||columnType.contains("json")) {
            fileType = String.class.getSimpleName();
        } else if (columnType.contains("decimal")||columnType.contains("number")) {
            fileType = String.class.getSimpleName();
//            //如果startKh大于等于0，则表示有设置取值范围
//            int startKh=columnLine.indexOf("(");
//            if(startKh>=0){
//                int endKh=columnLine.indexOf(")",startKh);
//                String[] fanwei=columnLine.substring(startKh+1,endKh).split("，");
//                //如果括号里是1位或者2位且第二位为0，则进行特殊处理。只有有小数位，都设置为BigDecimal。
//                if((fanwei.length>1&&"0".equals(fanwei[1]))||fanwei.length==1){
//                    int length=Integer.parseInt(fanwei[0]);
//                    if(fanwei.length>1) {
//                        length=Integer.valueOf(fanwei[1]);
//                    }
//                    //数字范围9位及一下用Integer，大的用Long
//                    if(length<=9){
//                        fileType = Integer.class.getSimpleName();
//                    }else{
//                        fileType = Long.class.getSimpleName();
//                    }
//                }else{
//                    //有小数位数一律使用BigDecimal
//                    fileType = BigDecimal.class.getSimpleName();
//                }
//            }else{
//                fileType = BigDecimal.class.getSimpleName();
//            }
        } else if (columnType.contains("boolean")) {
            fileType = Boolean.class.getSimpleName();
        } else {
            fileType = String.class.getSimpleName();
        }
        map.put("length1", length1);
        map.put("length2", length2);
        map.put("fileType",fileType);
        return map;
    }


    /**
     * 根据编号删除用户
     *
     * @param id
     */
    @Transactional(readOnly = false)
    public AR deleteById(String id){
        if (StringUtil.isEmpty(id)){
            return AR.failed("ID为空");
        }else{
            generatorFiledDao.physicalDeleteByTableId(id);
            dao.physicalDeleteById(id);
            return AR.ok("删除成功");
        }
    }

    /**
     * 创建新表
     * @param configure
     * @param generatorTable
     * @throws Exception
     */
    private void createTable(GeneratorConfigure configure, GeneratorTable generatorTable){
        String tableName = generatorTable.getTableName();
        /***保存数据库中表***/
        /**生成java类名，判断是否驼峰转换*********/
        if(configure.getNameCaseType().equals("2")){
            generatorTable.setClassName(StringUtil.underlineToCamel2(tableName));
            /***自动生成模块名和文件夹名*********/
            String[] moudleFile = tableName.split("_");
            generatorTable.setMoudleName(moudleFile[0]);
            if(moudleFile[1] != null) {
                StringBuffer fileDirName = new StringBuffer();
                for(int i=1;i<moudleFile.length;i++){
                    if(i > 1)
                        fileDirName.append(StringUtil.upperCaseFirst(moudleFile[i]));
                    else
                        fileDirName.append(moudleFile[i]);
                }
                generatorTable.setFileDirName(fileDirName.toString());
            }
            //权限
            generatorTable.setShiro(generatorTable.getFileDirName());
        }else{
            generatorTable.setClassName(tableName);
            /***自动生成模块名和文件夹名********/
            String[] moudleFile = StringUtil.camelToUnderline(tableName).split("_");
            generatorTable.setMoudleName(moudleFile[0]);
            if(moudleFile[1] != null){
                StringBuffer fileDirName = new StringBuffer();
                for(int i=1;i<moudleFile.length;i++){
                    if(i > 1)
                        fileDirName.append(StringUtil.upperCaseFirst(moudleFile[i]));
                    else
                        fileDirName.append(moudleFile[i]);
                }
                generatorTable.setFileDirName(fileDirName.toString());
            }
            //权限
            generatorTable.setShiro(generatorTable.getFileDirName());
        }
        dao.insert(generatorTable);
        /***查询列名并保存******/
        List<GeneratorField> generatorFiledList = generatorFiledDao.listTableColumn(tableName);
        for (GeneratorField generatorFiled : generatorFiledList){
            generatorFiled.setTableId(generatorTable.getId());
            /***生成java列名，判断是否驼峰转换***/
            if(configure.getNameCaseType().equals("2")){
                generatorFiled.setFieldName(StringUtil.underlineToCamel2(generatorFiled.getColumnName()));
            }else{
                generatorFiled.setFieldName(generatorFiled.getColumnName());
            }
            /********生成java列类型，和字段长度*********/
            Map<String,Object> map = getFileTypeByDataType(generatorFiled.getColumnType(),
                    configure.getTinyintTransType());
            generatorFiled.setFieldType(map.get("fileType").toString());
            generatorFiled.setColumnLength1(Integer.valueOf(map.get("length1").toString()));
            generatorFiled.setColumnLength2(Integer.valueOf(map.get("length2").toString()));
            /*********判断是否展示在页面中**********/
            if(generatorFiled.getFieldName().equals("id") || generatorFiled.getFieldName().equals("isDelete") || generatorFiled.getFieldName().equals("userId")
                || generatorFiled.getFieldName().equals("dateCreate") || generatorFiled.getFieldName().equals("dateUpdate")){
                generatorFiled.setListShow("0");
                generatorFiled.setInputType("0");
            }
            //添加字段
            generatorFiledDao.insert(generatorFiled);
        }
    }

    /*****代码生成器**********/
    @Transactional(readOnly = false)
    public AR generatorCreate(String id) throws Exception{
        /**配置表基础设置**/
        GeneratorConfigure configure = GeneratorUtil.get();
        GeneratorTable generatorTable = getById(id);
        generatorTable.setFieldList(generatorFiledDao.getByTableId(id));

        generatorTable.setInputTypes(ListUtil.listToStrings(generatorFiledDao.listInputTypes(id)));

        generatorTable.setParamNameList(generatorFiledDao.listParamNames(id));

        //是否含有查询
        generatorTable.setHasQuery(generatorFiledDao.getQueryNum(id));

        Map<String, Object> params = new HashMap<>();
        params.put("configure",configure);
        params.put("generatorTable",generatorTable);

        if(generatorTable.getNeedFile().contains("1")){
            FileUtil.generateToJava(generatorTable.getPageModel(), FreemarketConfigUtil.TYPE_MAPPER, params, configure, generatorTable);
        }
        if(generatorTable.getNeedFile().contains("2")){
            FileUtil.generateToJava(generatorTable.getPageModel(), FreemarketConfigUtil.TYPE_MODEL, params, configure, generatorTable);
        }
        if(generatorTable.getNeedFile().contains("3")){
            FileUtil.generateToJava(generatorTable.getPageModel(), FreemarketConfigUtil.TYPE_DAO, params, configure, generatorTable);
        }
        if(generatorTable.getNeedFile().contains("4")){
            FileUtil.generateToJava(generatorTable.getPageModel(), FreemarketConfigUtil.TYPE_SERVICE, params, configure, generatorTable);
        }
        if(generatorTable.getNeedFile().contains("5")){
            FileUtil.generateToJava(generatorTable.getPageModel(), FreemarketConfigUtil.TYPE_ACTION, params, configure, generatorTable);
        }
        if(generatorTable.getNeedFile().contains("6")){
            FileUtil.generateToJava(generatorTable.getPageModel(), FreemarketConfigUtil.PAGE_LIST, params, configure, generatorTable);
        }
        if(generatorTable.getNeedFile().contains("7")){
            FileUtil.generateToJava(generatorTable.getPageModel(), FreemarketConfigUtil.PAGE_INPUT, params, configure, generatorTable);
        }
        if(generatorTable.getNeedFile().contains("8")){
            FileUtil.generateToJava(generatorTable.getPageModel(), FreemarketConfigUtil.PAGE_SELECT, params, configure, generatorTable);
        }

        //父级菜单不为空，建立菜单
        if(StringUtil.isNotEmpty(generatorTable.getMenuParentId())){
            String name = generatorTable.getTableComment() + "管理";
            String shiro = generatorTable.getMoudleName() + ":" +
                    generatorTable.getShiro();
            //菜单建立
            Menu menu = menuService.getByNameAndShiro(name,shiro);
            //判断是否有菜单
            if(menu == null){
                menu = new Menu();
                menu.setName(name);
                menu.setHref("/" + generatorTable.getMoudleName() + "/" +
                        generatorTable.getShiro() + "/list");
                menu.setParentId(generatorTable.getMenuParentId());
                menu.setIsShow("1");
                menu.setHasChild(0);
                menu.setSort(0);
                menu.setShiro(shiro);
                menuService.save(menu);
            }
            /**为超级管理员授权**/
//            MenuRole menuRole = new MenuRole();
//            menuRole.setRoleId("1");
//            menuRole.setMenuId(menu.getId());
//            menuRoleDao.insert(menuRole);
        }

        generatorTable.setIsAlready("1");
        dao.updateById(generatorTable);
        return AR.ok("代码生成成功，启动系统生效");
    }

    @Transactional(readOnly = false)
    public AR generatorDelete(String id) throws Exception{
        GeneratorConfigure configure = GeneratorUtil.get();
        GeneratorTable generatorTable = getById(id);
        generatorTable.setFieldList(generatorFiledDao.getByTableId(id));
        FileUtil.deleteToJava(configure, generatorTable);
        generatorTable.setIsAlready("0");
        dao.updateById(generatorTable);

        return AR.ok("代码删除成功，启动系统生效");
    }
}
